﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MageWars.Support;
using Microsoft.Xna.Framework;
using MageWars.Support.StateMachines.States;

namespace MageWars.GameElements
{
    public class AiMage : Mage
    {
        private static Random rand = new Random();
        private const float NormalRotation = MathHelper.PiOver2;
        private const float GreatRotation = MathHelper.Pi;
        private const float Collision_Risk = 10f;
        private Random randy = new Random();

        public StateMachine SM { get; set; }

        public override StateMachine GetSM()
        {
            return SM;
        }

        public AiMage()
        {

        }

        public AiMage(Vector3 Position, Team Group)
        {
            this.Group = Group;
            SM = new StateMachine(this);
            this.Position = Position;
            SM.CurrentState = new Guard(this, new Vector2(100, 650));
            this.HP = 100;
        }

        public IEnumerable<Node> GetCamino()
        {
            return SM.CurrentState.GetCamino();
        }


        public MWAction ProcesarCamposPotenciales(MWAction MaqDeEstado)
        {
            MWAction result = MaqDeEstado;

            foreach (var m in Mage.Mages)
            {
                var dist = MageMath.GetDistance(this.Position, m.Position);
                if (dist < RadioDeCampo)
                {
                    result.Speed = result.Speed * -1;
                    break;
                }
            }

            return result;
        }

        private const int RadioDeCampo = 10;
		
        public Vector3 GetNewPosition(StateMachine SM, float speed) 
        {
            if (GetCamino().Count() > 0)
            {
                Vector3 targetPosition = new Vector3(GetCamino().First().Position.X, GetCamino().First().Position.Y, 0);
                float pullDistance = Vector3.Distance(targetPosition, this.Position);

                if (pullDistance > this.radio)
                {
                    Vector3 pull = (targetPosition - this.Position) * (1 / pullDistance);
                    Vector3 totalPush = Vector3.Zero;
                    int contenders = 0;
                    foreach (var m in Mage.Mages)
                    {
                        if (m != this)
                        {
                            //draw a vector from the obstacle to the ship, that 'pushes the ship away'
                            Vector3 push = this.Position - m.Position;

                            //calculate how much we are pushed away from this obstacle, the closer, the more push
                            float distance = (Vector3.Distance(this.Position, m.Position) - m.radio) - this.radio;
                            //only use push force if this object is close enough such that an effect is needed
                            if (distance < this.radio * 3)
                            {
                                ++contenders; //count that this object is actively pushing

                                if (distance < 0.0001f) //prevent division by zero errors and extreme pushes
                                {
                                    distance = 0.0001f;
                                }
                                float weight = 1 / distance;
                                totalPush += push * weight;
                            }
                        }
                    }

                    pull *= Math.Max(1, 4 * contenders); //4 * contenders gives the pull enough force to pull stuff trough (tweak this setting for your game!)
                    pull += totalPush;

                    //Normalize the vector so that we get a vector that points in a certain direction, which we van multiply by our desired speed
                    pull.Normalize();
                    //Set the ships new position;
                    return (this.Position + (pull * speed));
                }
                else
                {
                    float x = this.Position.X + (float)Math.Cos(Direction) * speed;
                    float y = this.Position.Y + (float)Math.Sin(Direction) * speed;

                    return new Vector3(x, y, 0);
                }
            }
            else
            {
                float x = this.Position.X + (float)Math.Cos(Direction) * speed;
                float y = this.Position.Y + (float)Math.Sin(Direction) * speed;

                return new Vector3(x, y, 0);
            }
        }

        public override void UpdatePosition()
        {
            var r = SM.GetNextAction();
            //r = ProcesarCamposPotenciales(r);
            this.Direction = r.Direction.HasValue ? r.Direction.Value : this.Direction;
            if (r.Speed.HasValue)
            {
                //float x = Position.X + (float)Math.Cos(Direction) * r.Speed.Value;
                //float y = Position.Y + (float)Math.Sin(Direction) * r.Speed.Value;

                //var nv = new Vector3(x, y, 0);
                var nv = GetNewPosition(SM, r.Speed.Value);

                //Vector por si el mago choca
                float xx = Position.X - 10*((float)Math.Cos(Direction) * r.Speed.Value);
                float yy = Position.Y - 10*((float)Math.Sin(Direction) * r.Speed.Value);

                var nnv = new Vector3(xx, yy, 0);
                Vector3 old_pos = Vector3.Zero;
                
                if (!CheckCollisions())
                    Position = nv;
                else
                {
                    Position = nnv;
                }
            }

            if (r.Fire)
            {
                Fire();
            }


        }
    }
}
